package com.keguoyu.easymvp.ioc.origin

import com.android.build.api.transform.Context
import com.android.build.api.transform.TransformInput
import com.android.build.api.transform.TransformOutputProvider
import com.keguoyu.easymvp.ioc.internal.CacheUtils
import com.keguoyu.easymvp.ioc.internal.InvokerCache
import com.keguoyu.easymvp.ioc.internal.util.TimeTracker
import com.keguoyu.easymvp.ioc.internal.util.loopAllFiles
import com.keguoyu.easymvp.ioc.internal.util.loopAllJars
import org.gradle.api.Project
import java.io.File

class InvokerTransformer(private val mProject: Project) {
  fun transform(context: Context, inputs: Collection<TransformInput>,
                outputProvider: TransformOutputProvider, isIncremental: Boolean) {
    println("invoker isIncremental ${isIncremental}")
    val tracker = TimeTracker("invoker")
    val (info, allFileSet) = FileScanner()
      .scan(inputs, outputProvider)
    tracker.taskFinish("scan")
    val changed = InvokerCache(CacheUtils.getCachePath(mProject))
        .compareAndSaveInvokerInfos(info)
    val fullBuild = !isIncremental || changed
    tracker.taskFinish("compare fullBuld ${fullBuild}")
    val (copiedFiles, copiedJars) = FileCopier(
      fullBuild).copy(inputs, outputProvider)
    tracker.taskFinish("copy")
    val (changedFiles, changedJars) = calculateDiff(changed, inputs, outputProvider, copiedFiles, copiedJars)
    FileModifier(info,
            context.path.contains("Debug") || context.path.contains("run"),
            allFileSet)
            .modify(changedFiles, changedJars)
    tracker.taskFinish("modify files")
  }

  private fun calculateDiff(fullBuild: Boolean,
                            inputs: Collection<TransformInput>,
                            outputProvider: TransformOutputProvider,
                            copiedFiles: Set<File>,
                            copiedJars: Set<File>): Pair<Collection<File>, Collection<File>> {
    val filesNeedsTransform: Set<File>
    val jarsNeedsTransform: Set<File>
    if (fullBuild) {
      filesNeedsTransform = HashSet()
      jarsNeedsTransform = HashSet()
      inputs.forEach {
        it.loopAllFiles(outputProvider) { _, fout, _ ->
          filesNeedsTransform.add(fout)
        }
        it.loopAllJars(outputProvider) { _, dest ->
          jarsNeedsTransform.add(dest)
        }
      }
    } else {
      filesNeedsTransform = copiedFiles
      jarsNeedsTransform = copiedJars
    }
    return Pair(filesNeedsTransform, jarsNeedsTransform)
  }
}